package com.zeyu.framework.tools.console.service;

import com.beust.jcommander.internal.Lists;
import com.google.common.collect.Maps;
import com.zeyu.framework.core.service.CrudService;
import com.zeyu.framework.tools.console.dao.ConsoleParamDao;
import com.zeyu.framework.tools.console.entity.BasicConfiguration;
import com.zeyu.framework.tools.console.entity.ConsoleParam;
import com.zeyu.framework.tools.console.entity.RDPConfiguration;
import com.zeyu.framework.tools.console.entity.SSHConfiguration;
import com.zeyu.framework.tools.console.entity.TelnetConfiguration;
import com.zeyu.framework.tools.console.entity.VNCConfiguration;
import com.zeyu.framework.utils.Collections3;
import com.zeyu.framework.utils.StringUtils;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.MapUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Map;

/**
 * console配置Service
 */
@Service
@Transactional(readOnly = true)
public class ConsoleParamService extends CrudService<ConsoleParamDao, ConsoleParam> {

    // ================================================================
    // Constants
    // ================================================================

    // ================================================================
    // Fields
    // ================================================================

    // ================================================================
    // Constructors
    // ================================================================

    // ================================================================
    // Methods from/for super Interfaces or SuperClass
    // ================================================================

    /**
     * 根据类型获取全部配置
     * @param type 协议类型,为空或其他则是全部
     */
    public List<BasicConfiguration> findByType(String type) {
        List<BasicConfiguration> configurations = Lists.newArrayList();

        List<ConsoleParam> params;
        if (StringUtils.isEmpty(type) || StringUtils.equals(type, ConsoleParam.TYPE_ALL)) {
            params = dao.findList(new ConsoleParam());
        } else {
            ConsoleParam param = new ConsoleParam();
            param.setType(type);
            params = dao.findByType(param);
        }

        if (!Collections3.isEmpty(params)) {
            try {
                Map<String, Map<String, String>> ckvs = Maps.newHashMap();
                for (ConsoleParam param : params) {
                    if (ckvs.containsKey(param.getConnId())) {
                        ckvs.get(param.getConnId()).put(param.getLabel(), param.getValue());
                    } else {
                        Map<String, String> kvs = Maps.newHashMap();
                        kvs.put(param.getLabel(), param.getValue());
                        ckvs.put(param.getConnId(), kvs);
                    }
                }
                for (Map.Entry<String, Map<String, String>> kvs : ckvs.entrySet()) {
                    BasicConfiguration configuration = buildConfiguration(kvs.getValue().get("protocol"), kvs.getValue());

                    configuration.setId(kvs.getKey());
                    configurations.add(configuration);
                }
            } catch (Exception e) {
                logger.error("build configuration error: ", e);
            }
        }

        return configurations;
    }

    /**
     * 根据连接id获取配置信息
     */
    public BasicConfiguration findByConnId(String connId) {

        BasicConfiguration configuration = null;
        List<ConsoleParam> params = dao.findByConnId(new ConsoleParam(connId));
        if (!Collections3.isEmpty(params)) {
            try {
                Map<String, String> kvs = Maps.newHashMap();
                for (ConsoleParam param : params) {
                    kvs.put(param.getLabel(), param.getValue());
                }
                // 使用bean拷贝
                configuration = buildConfiguration(params.get(0).getType(), kvs);
                configuration.setId(params.get(0).getConnId());
            } catch (Exception e) {
                logger.error("build configuration error: ", e);
            }
        }

        return configuration;
    }

    /**
     * 保持配置信息
     */
    @Transactional
    public void save(BasicConfiguration configuration) {

        try {
            // bean转换为map
            Map<String, String> kvs = BeanUtils.describe(configuration);

            if (MapUtils.isNotEmpty(kvs)) {
                ConsoleParam consoleParam;
                for (Map.Entry<String, String> kv : kvs.entrySet()) {
                    if (kv.getValue() != null && !StringUtils.equals(kv.getKey(), "class")) {
                        consoleParam = new ConsoleParam();
                        consoleParam.setConnId(configuration.getId());
                        consoleParam.setType(configuration.getProtocol());
                        // 设置key value
                        consoleParam.setLabel(kv.getKey());
                        consoleParam.setValue(kv.getValue());
                        consoleParam.preInsert();
                        dao.insert(consoleParam);
                    }
                }
            }
        } catch (Exception e) {
            logger.error("convert configuration error: ", e);
        }
    }

    /**
     * 删除连接id下所有配置
     */
    @Transactional
    public void delete(String connId) {
        dao.deleteByConnId(new ConsoleParam(connId));
    }

    // ================================================================
    // Public or Protected Methods
    // ================================================================

    // ================================================================
    // Getter & Setter
    // ================================================================

    // ================================================================
    // Private Methods
    // ================================================================

    /**
     * 根据类型获取配置类
     */
    private BasicConfiguration buildConfiguration(String protocol, Map<String, String> vals) throws InvocationTargetException, IllegalAccessException {
        BasicConfiguration configuration;

        // 构建各种配置类
        if (StringUtils.equals(protocol, ConsoleParam.TYPE_SSH)) {
            configuration = new SSHConfiguration();
        } else if (StringUtils.equals(protocol, ConsoleParam.TYPE_RDP)) {
            configuration = new RDPConfiguration();
        } else if (StringUtils.equals(protocol, ConsoleParam.TYPE_TELNET)) {
            configuration = new TelnetConfiguration();
        } else if (StringUtils.equals(protocol, ConsoleParam.TYPE_VNC)) {
            configuration = new VNCConfiguration();
        } else {
            configuration = new BasicConfiguration();
        }
        // 使用bean拷贝
        BeanUtils.copyProperties(configuration, vals);

        return configuration;
    }

    // ================================================================
    // Inner or Anonymous Class
    // ================================================================

    // ================================================================
    // Test Methods
    // ================================================================
}
